#include <stdio.h>
#include <stdlib.h>
 
/* 定义WORD为两个字节的类型 */
typedef unsigned short WORD;
/* 定义DWORD为四个字节的类型 */
typedef unsigned long DWORD;
 
/* 位图文件头主要是对位图文件的一些描述 位图信息头主要是对位图图像方面信息的描述 */
/*************************** 位图标准信息(54字节) ******************************************/
/* 位图文件头 （位图头的字节数 = 位图文件字节数 - 位图图像数据字节数）*/
typedef struct BMP_FILE_HEADER
{
	WORD bType;      // 文件标识符 
	DWORD bSize;     // 文件的大小 
	WORD bReserved1; // 保留值,必须设置为0  
	WORD bReserved2; // 保留值,必须设置为0 
	DWORD bOffset;   // 文件头的最后到图像数据位开始的偏移量 
} BMPFILEHEADER;     // 14 字节
 
/* 位图信息头 */
typedef struct BMP_INFO
{
	DWORD bInfoSize;            // 信息头的大小   
	DWORD bWidth;               // 图像的宽度     
	DWORD bHeight;              // 图像的高度     
	WORD bPlanes;               // 图像的位面数   
	WORD bBitCount;             // 每个像素的位数 
	DWORD bCompression;         // 压缩类型 
	DWORD bmpImageSize;         // 图像的大小,以字节为单位 
	DWORD bXPelsPerMeter;       // 水平分辨率 
	DWORD bYPelsPerMeter;       // 垂直分辨率 
	DWORD bClrUsed;             // 使用的色彩数 
	DWORD bClrImportant;        // 重要的颜色数 
} BMPINF;            // 40 字节
 
/* 彩色表:调色板 */
typedef struct RGB_QUAD 
{
	WORD rgbBlue;     // 蓝色强度 
	WORD rgbGreen;    // 绿色强度 
	WORD rgbRed;      // 红色强度 
	WORD rgbReversed; // 保留值 
} RGBQUAD;
 
 
int main(int argc,char * argv[])
{
    if(argc < 2)
    {
        printf("error");
        return 0;
    }
	int i = sizeof(BMPFILEHEADER);
	int j = sizeof(long);
	FILE *fp;                     // 定义一个文件指针
	BMPFILEHEADER bmpFileHeader;  // 定义一个 BMP 文件头的结构体
	BMPINF bmpInfo;               // 定义一个 BMP 文件信息结构体 
 
	// "rb" 只读打开一个二进制文件，只允许读数据。'b'指的是让这个库函数以二进制形式打开此文件。
	// 读取失败会返回空指针，读取成功后，fp 会指向一块具有 bmp 属性的内存,我们可以对这块内存开始操作
	if((fp = fopen(argv[1], "rb")) == NULL) // fp = 0x00426aa0
	{
		printf("Cann't open the file!\n");
		return 0;
	}
 
	// 让 fp 指向 bmp 文件的开始 
	// 第 2 个参数是偏移量 第三个参数是文件起始地址 所以此函数执行成功后文件指针会指向文件的开始
	fseek(fp, 0, SEEK_SET);                            // fp = 0x00426aa0
 
	// 读取文件信息
	/*
		参数1: 读出数据的存放缓冲区
		参数2: 读取多少个字节的数据
		参数3: 读取几包这样的数据
		参数4: 文件指针（源数据）
	*/
	fread(&bmpFileHeader, sizeof(BMPFILEHEADER), 1, fp); 
	
	fread(&bmpInfo, sizeof(bmpInfo), 1, fp);
 
 
	// 输出BMP文件的位图文件头的所有信息
	// printf("位图文件头主要是对位图文件的一些描述:BMPFileHeader\n\n");
	// printf("文件标识符 = 0X%X\n", bmpFileHeader.bType);
	// printf("BMP 文件大小 = %d 字节\n", bmpFileHeader.bSize);
	// printf("保留值1 = %d \n", bmpFileHeader.bReserved1);
	// printf("保留值2 = %d \n", bmpFileHeader.bReserved2);
	// printf("文件头的最后到图像数据位开始的偏移量 = %d 字节\n", bmpFileHeader.bOffset);
 
	// 输出BMP文件的位图信息头的所有信息
	// printf("\n\n位图信息头主要是对位图图像方面信息的描述:BMPInfo\n\n");
	// printf("信息头的大小 = %d 字节\n", bmpInfo.bInfoSize);
	printf("位图的高度 = %ld \n", bmpInfo.bHeight);
	printf("位图的宽度 = %ld \n", bmpInfo.bWidth);
	// printf("图像的位面数(位面数是调色板的数量,默认为1个调色板) = %d \n", bmpInfo.bPlanes); 
	// printf("每个像素的位数 = %d 位\n", bmpInfo.bBitCount);
	// printf("压缩类型 = %d \n", bmpInfo.bCompression);
	// printf("图像的大小 = %d 字节\n", bmpInfo.bmpImageSize);
	printf("水平分辨率 = %ld \n", bmpInfo.bXPelsPerMeter);
	printf("垂直分辨率 = %ld \n", bmpInfo.bYPelsPerMeter);
	// printf("使用的色彩数 = %d \n", bmpInfo.bClrUsed);
	// printf("重要的色彩数 = %d \n", bmpInfo.bClrImportant);
 
	// printf("\n\n\n压缩说明：有0（不压缩），1（RLE 8，8位RLE压缩），2（RLE 4，4位RLE压缩，3（Bitfields，位域存放）");
 
	fclose(fp);
 
	//while(1);
 
	return 0;
 
}